import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:zhibao_flutter/api/mine/mine_entity.dart';
import 'package:zhibao_flutter/api/mine/mine_view_model.dart';
import 'package:zhibao_flutter/api/user/user_entity.dart';
import 'package:zhibao_flutter/api/user/user_model.dart';
import 'package:zhibao_flutter/util/check/check.dart';
import 'package:zhibao_flutter/util/config/config_route.dart';
import 'package:zhibao_flutter/util/config/sp_key.dart';
import 'package:zhibao_flutter/util/data/q1_data.dart';
import 'package:zhibao_flutter/util/func/log.dart';
import 'package:zhibao_flutter/util/func/sp_util.dart';
import 'package:zhibao_flutter/util/http/http.dart';
import 'package:zhibao_flutter/util/ui/my_toast.dart';
import 'package:zhibao_flutter/widget/dialog/confirm_dialog.dart';
import 'package:zhibao_flutter/widget/view/hud_view.dart';
import 'package:get/get.dart';
// import 'package:rongcloud_im_plugin/rongcloud_im_plugin.dart';

UserViewModel userViewModel = UserViewModel();

class UserViewModel extends BaseViewModel {
  static bool isTemporaryTapProcessingFormLogin = false;

  static void restoreTemporaryProcessFormLogin([int milliseconds = 500]) {
    Future.delayed(Duration(milliseconds: milliseconds)).then((value) {
      isTemporaryTapProcessingFormLogin = false;
    });
  }

  /*
  * SecurityRegisterRequestModel
  *
  **/
  Future<ResponseModel> securityLogin(
    BuildContext context, {
    required final String username,
    required final String password,
  }) async {
    if (!strNoEmpty(username)) {
      myFailToast('enterPhoneEmail'.tr);
      return ResponseModel.fromSuccess(null);
    }
    if (!strNoEmpty(password)) {
      myFailToast('enterPassword'.tr);
      return ResponseModel.fromSuccess(null);
    }
    return SecurityLoginRequestModel(username, password)
        .sendApiAction(
      context,
      reqType: ReqType.post,
      // isFetchResult: false,
    )
        .then((rep) {
      return ResponseModel.fromSuccess(rep);
    }).catchError((e) {
      return throwError(e);
    }).onError((error, stackTrace) {
      return onError(error, stackTrace);
    });
  }

  // Future loginApiAfter(
  //     BuildContext context, String token, TextEditingController phoneC) async {
  //   LogUtil.d("[${this.toString()}] loginApiAfter token is $token");
  //
  //   if (!strNoEmpty(token)) {
  //     myToast('获取token失败');
  //     return;
  //   }
  //
  //   /// 设置临时token
  //   Q1Data.tempToken = token;
  //
  //   /// 临时手机号/邮箱
  //   Q1Data.tempPhone = phoneC.text;
  //
  //   /// Check user info
  //   final selfInfo = await mineViewModel.getSelfInfo(context);
  //   if (selfInfo.data == null) {
  //     return;
  //   }
  //
  //
  //   /// 判断是否有选择性别和头像昵称年龄等必有的信息，
  //   /// 如果没有的话跳转选择性别
  //   UserInfoEntity userInfoEntity = selfInfo.data;
  //
  //     /// 真正处理登录
  //     userViewModel.loginHandle(userInfoEntity, phoneC.text);
  // }

/*
  * Login handle.
  * */
  Future loginHandle(LoginRspEntity entity, String mobile) async {
    if (Get.context != null) {
      /// Avoid has focus of textField.
      FocusScope.of(Get.context!).requestFocus(FocusNode());
    }

    SpUtil().setString(SpKey.loginResult, json.encode(entity));
    LogUtil.d('[loginHandle] Store value is ${json.encode(entity)}');

    /// Save login phone.
    await SpUtil().setString(SpKey.loginPhone, mobile);

    /// Init local data.
    await Q1Data.init();

    try {
      /// Get user base info.
      await userIndex(entity);
    } catch (e) {
      LogUtil.d("Get base info error.${e.toString()}");
      myToast('getUserInfoError'.tr);
    }
    if (Q1Data.userInfoEntity != null) {
      /// Jump to home page.
      Get.offAllNamed(RouteConfig.mainPage);
    }
  }

  Future userIndex(LoginRspEntity loginRspEntity) async {
    await mineViewModel.getSelfInfo(null, loginRspEntity.token!);
  }

/*
* RegisterRequestModel
*
**/
  Future<ResponseModel> register(
    BuildContext context, {
    required final String checkCode,
    required final String inviteCode,
    required final String password,
    required final String account,
  }) async {
    return RegisterRequestModel(
      checkCode,
      inviteCode,
      password,
      account,
    )
        .sendApiAction(
      context,
      reqType: ReqType.post,
    )
        .then((rep) {
      return ResponseModel.fromSuccess(rep ?? true);
    }).catchError((e) {
      return throwError(e);
    }).onError((error, stackTrace) {
      return onError(error, stackTrace);
    });
  }

  /*
  * ChangePswRequestModel
  *
  **/
  Future<ResponseModel> changePsw(
    BuildContext context, {
    required final String checkCode,
    required final String inviteCode,
    required final String password,
    required final String account,
  }) async {
    return ChangePswRequestModel(
      checkCode,
      inviteCode,
      password,
      account,
    )
        .sendApiAction(
      context,
      reqType: ReqType.post,
    )
        .then((rep) {
      return ResponseModel.fromSuccess(rep ?? true);
    }).catchError((e) {
      return throwError(e);
    }).onError((error, stackTrace) {
      return onError(error, stackTrace);
    });
  }

  /*
  * UserUpdatePayPasswordRequestModel
  *
  **/
  Future<ResponseModel> userUpdatePayPassword(
    BuildContext context, {
    required final String checkCode,
    required final String password,
    required final String account,
  }) async {
    return UserUpdatePayPasswordRequestModel(
      checkCode,
      password,
      account,
    )
        .sendApiAction(
      context,
      reqType: ReqType.post,
    )
        .then((rep) {
      return ResponseModel.fromSuccess(rep ?? true);
    }).catchError((e) {
      return throwError(e);
    }).onError((error, stackTrace) {
      return onError(error, stackTrace);
    });
  }

  /*
  * LogoFFRequestModel
  *
  **/
  Future<ResponseModel> logoFF(
    BuildContext context, {
    required final String reason,
    required final String check_code,
  }) async {
    return LogoFFRequestModel(
      reason,
      check_code,
    )
        .sendApiAction(
      context,
      reqType: ReqType.post,
    )
        .then((rep) async {
      try {
        HudView.show(Get.context);
        await Q1Data.loginOut();
        await Future.delayed(Duration(milliseconds: 200));
        HudView.dismiss();
      } catch (e) {
        LogUtil.d("注销退出登录出现错误，${e.toString()}");
      }
      return ResponseModel.fromSuccess(rep);
    }).catchError((e) {
      return throwError(e);
    }).onError((error, stackTrace) {
      return onError(error, stackTrace);
    });
  }

  /*
  * SetPushIdRequestModel
  *
  **/
  Future<ResponseModel> setPushId(
    BuildContext context, {
    required final String push_id,
  }) async {
    return SetPushIdRequestModel(
      push_id,
    )
        .sendApiAction(
      context,
      reqType: ReqType.post,
    )
        .then((rep) {
      return ResponseModel.fromSuccess(rep);
    }).catchError((e) {
      return throwError(e);
    }).onError((error, stackTrace) {
      return onError(error, stackTrace);
    });
  }

  /*
  * SendCodeLoginRequestModel
  *
  **/
  Future<ResponseModel> sendCodeLogin(
    BuildContext context, {
    required final String account,
    required final int type,
  }) async {
    if (!strNoEmpty(account)) {
      myFailToast('enterPhoneEmail'.tr);
      return ResponseModel.fromSuccess(null);
    }
    return SendCodeLoginRequestModel(
      account,
      type,
    )
        .sendApiAction(
      context,
      reqType: ReqType.post,
    )
        .then((rep) {
      return ResponseModel.fromSuccess(rep);
    }).catchError((e) {
      return throwError(e);
    }).onError((error, stackTrace) {
      return onError(error, stackTrace);
    });
  }

  /*
  * RefreshImTokenRequestModel
  *
  **/
  Future<ResponseModel> refreshImToken(BuildContext? context) async {
    return RefreshImTokenRequestModel()
        .sendApiAction(
      context,
      reqType: ReqType.post,
    )
        .then((rep) {
      return ResponseModel.fromSuccess(rep['im_token']);
    }).catchError((e) {
      return throwError(e);
    }).onError((error, stackTrace) {
      return onError(error, stackTrace);
    });
  }

  /*
  * GetLogoFFReasonRequestModel
  *
  **/
  Future<ResponseModel> getLogOffReason(BuildContext context) async {
    return GetLogoFFReasonRequestModel()
        .sendApiAction(
      context,
      reqType: ReqType.post,
    )
        .then((rep) {
      return ResponseModel.fromSuccess(rep);
    }).catchError((e) {
      return throwError(e);
    }).onError((error, stackTrace) {
      return onError(error, stackTrace);
    });
  }

  Future loginOut() async {
    HudView.show(Get.context);
    await Q1Data.loginOut();
    await Future.delayed(Duration(milliseconds: 200));
    HudView.dismiss();
    Get.offAllNamed(RouteConfig.loginPage);
  }

  Future<bool> loginOff({VoidCallback? onSuccess}) async {
    /// 防止多个事件一起点
    if (isTemporaryTapProcessingFormLogin) {
      return false;
    }
    isTemporaryTapProcessingFormLogin = true;
    restoreTemporaryProcessFormLogin(300);

    if (onSuccess != null) onSuccess();
    try {
      await Q1Data.loginOut(verify: false);
      await Future.delayed(Duration(milliseconds: 200));
      Get.offAllNamed(RouteConfig.loginPage);
    } catch (e) {
      LogUtil.d("loginOff::Error:${e.toString()}");
      return true;
    }
    return true;
  }

  /*
  * AddAdviseRequestModel
  *
  **/
  Future<ResponseModel> addAdvise(
    BuildContext context, {
    required String content,
  }) async {
    return AddAdviseRequestModel(
      content,
    )
        .sendApiAction(
      context,
      reqType: ReqType.post,
    )
        .then((rep) {
      return ResponseModel.fromSuccess(rep);
    }).catchError((e) {
      return throwError(e);
    }).onError((error, stackTrace) {
      return onError(error, stackTrace);
    });
  }

  /*
  * YaoqingrenUserIndexRequestModel
  *
  **/
  Future<ResponseModel> yaoqingrenUserIndex(
    BuildContext context, {
    OnData? onStore,
  }) async {
    return YaoqingrenUserIndexRequestModel()
        .sendApiAction(
      context,
      reqType: ReqType.post,
      onStore: onStore == null
          ? null
          : (rep) {
              onStore(YaoqingrenRspEntity.fromJson(rep));
            },
    )
        .then((rep) {
      YaoqingrenRspEntity rspEntity = YaoqingrenRspEntity.fromJson(rep);
      return ResponseModel.fromSuccess(rspEntity);
    }).catchError((e) {
      return throwError(e);
    }).onError((error, stackTrace) {
      return onError(error, stackTrace);
    });
  }

  /*
  * CoinToCashIndexRequestModel
  *
  **/
  Future<ResponseModel> coinToCashIndex(
    BuildContext? context, {
    required final int get_type,
  }) async {
    return CoinToCashIndexRequestModel(get_type)
        .sendApiAction(
      context,
      reqType: ReqType.post,
    )
        .then((rep) {
      RetiradaEntity retiradaEntity = RetiradaEntity.fromJson(rep);
      return ResponseModel.fromSuccess(retiradaEntity);
    }).catchError((e) {
      return throwError(e);
    }).onError((error, stackTrace) {
      return onError(error, stackTrace);
    });
  }

  /*
  * CoinToCashRequestModel
  *
  **/
  Future<ResponseModel> coinToCash(
    BuildContext context, {
    required final int amount,
  }) async {
    return CoinToCashRequestModel(amount)
        .sendApiAction(
      context,
      reqType: ReqType.post,
    )
        .then((rep) {
      return ResponseModel.fromSuccess(rep);
    }).catchError((e) {
      return throwError(e);
    }).onError((error, stackTrace) {
      return onError(error, stackTrace);
    });
  }

  /*
  * verify_token
  *
  **/
  Future<ResponseModel> checkConfirmH5(
    BuildContext context, {
    required String verify_token,
  }) async {
    return CheckConfirmH5RequestModel(
      verify_token,
    )
        .sendApiAction(
      context,
      reqType: ReqType.post,
    )
        .then((rep) {
      return ResponseModel.fromSuccess(rep);
    }).catchError((e) {
      return throwError(e);
    }).onError((error, stackTrace) {
      return onError(error, stackTrace);
    });
  }
}
